package org.langqiao.classloader;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;

/**
 * 自定义类加载器
 * 采用双亲委托机制
 * @author mingyangyang
 *
 */
public class MyClassloader extends ClassLoader{
	
	private String path = null;
	
	public MyClassloader(String path){
		this.path = path;
	}
	
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		Class<?> c = findLoadedClass(name);
		if(c != null){
			return c;
		}else{
			c = this.getParent().loadClass(name);
			if(c != null){
				return c;
			}else{
				//自己加载字节数组
				byte[] classData = getClassData1(name);
				if(classData == null){
					throw new ClassNotFoundException(name);
				}else{
					c = defineClass(name, classData, 0, classData.length);
				}
			}
		}
		return c;
    }
	
	public byte[] getClassData(String name){
		path = path + "/" + name.replace(".", "/") + ".class";
		InputStream is = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try {
			is = new FileInputStream(path);
			byte[] buffer = new byte[1024];
			int temp = 0;
			while((temp =is.read(buffer)) != -1){
				bos.write(buffer, 0, temp);;
			}
			return bos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}finally{
			if(is != null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bos != null){
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public byte[] getClassData1(String name){
		path = path + "/" + name.replace(".", "/") + ".class";
		InputStream is = null;
		try {
			is = new FileInputStream(path);
			return IOUtils.toByteArray(is);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}finally{
			if(is != null){
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}